/*
 * Copyright 2010 Emmanuel Roussel
 * http://rousselmanu.free.fr
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street,
 * Boston, MA 02110-1301, USA.
 */


#ifndef TETRIS_H
#define TETRIS_H

bit sleepy;

#define SCORE_LENGTH 38		//number of notes in the music score.
music_score tetris_theme[]={
	{N7_D,	N_NOIRE},
	{N6_A,	N_CROCHE},
	{N6_AD,	N_CROCHE},
	{N7_C,	N_NOIRE},
	{N6_AD,	N_CROCHE},
	{N6_A,	N_CROCHE},
	{N6_G,	N_NOIRE},
	{N6_G,	N_CROCHE},
	{N6_AD,	N_CROCHE},
	{N7_D,	N_NOIRE},
	{N7_C,	N_CROCHE},
	{N6_AD,	N_CROCHE},
	{N6_A,	N_NOIRE},
	{N6_A,	N_CROCHE},
	{N6_AD,	N_CROCHE},
	{N7_C,	N_NOIRE},
	{N7_D,	N_NOIRE},
	{N6_AD,	N_NOIRE},
	{N6_G,	N_NOIRE},
	{N6_G,	N_BLANCHE},	//20
	
	{N7_C,	N_NOIRE},
	{N7_DD,	N_CROCHE},
	{N7_G,	N_NOIRE},
	{N7_F,	N_CROCHE},
	{N7_DD,	N_CROCHE},
	{N7_D,	N_NOIRE},
	{N6_AD,	N_CROCHE},
	{N7_D,	N_NOIRE},
	{N7_C,	N_CROCHE},
	{N6_AD,	N_CROCHE},
	{N6_A,	N_NOIRE},
	{N6_A,	N_CROCHE},
	{N6_AD,	N_CROCHE},
	{N7_C,	N_NOIRE},
	{N7_D,	N_NOIRE},
	{N6_AD,	N_NOIRE},
	{N6_G,	N_NOIRE},
	{N6_G,	N_BLANCHE}	//38
};

static const u8 list_pieces[7][4][4] = {		//stolen from http://jumptuck.wordpress.com/2010/01/13/tetrapuzz-tetris-clone-for-avr/
		//T
		{
				{
						0b00000010,
						0b00000011,
						0b00000010,
						0b00000000
				},

				{
						0b00000000,
						0b00000111,
						0b00000010,
						0b00000000
				},

				{
						0b00000001,
						0b00000011,
						0b00000001,
						0b00000000
				},

				{
						0b00000010,
						0b00000111,
						0b00000000,
						0b00000000
				}
		},

		// S
		{
				{
						0b00000010,
						0b00000011,
						0b00000001,
						0b00000000
				},

				{
						0b00000011,
						0b00000110,
						0b00000000,
						0b00000000
				},

				{
						0b00000010,
						0b00000011,
						0b00000001,
						0b00000000
				},

				{
						0b00000011,
						0b00000110,
						0b00000000,
						0b00000000
				}
		},

		// Z
		{
				{
						0b00000001,
						0b00000011,
						0b00000010,
						0b00000000
				},

				{
						0b00000110,
						0b00000011,
						0b00000000,
						0b00000000
				},

				{
						0b00000001,
						0b00000011,
						0b00000010,
						0b00000000
				},

				{
						0b00000110,
						0b00000011,
						0b00000000,
						0b00000000
				}
		},

		// L
		{
				{
						0b00000011,
						0b00000001,
						0b00000001,
						0b00000000
				},

				{
						0b00000000,
						0b00000001,
						0b00000111,
						0b00000000
				},

				{
						0b00000010,
						0b00000010,
						0b00000011,
						0b00000000
				},

				{
						0b00000000,
						0b00000111,
						0b00000100,
						0b00000000
				}
		},

		// J
		{
				{
						0b00000001,
						0b00000001,
						0b00000011,
						0b00000000
				},

				{
						0b00000000,
						0b00000100,
						0b00000111,
						0b00000000
				},

				{
						0b00000011,
						0b00000010,
						0b00000010,
						0b00000000
				},

				{
						0b00000000,
						0b00000111,
						0b00000001,
						0b00000000
				}
		},

		// Box
		{
				{
						0b00000011,
						0b00000011,
						0b00000000,
						0b00000000,
				},

				{
						0b00000011,
						0b00000011,
						0b00000000,
						0b00000000,
				},

				{
						0b00000011,
						0b00000011,
						0b00000000,
						0b00000000,
				},

				{
						0b00000011,
						0b00000011,
						0b00000000,
						0b00000000,
				}
		},

		// Line
		{
				{
						0b00000001,
						0b00000001,
						0b00000001,
						0b00000001
				},

				{
						0b00000000,
						0b00001111,
						0b00000000,
						0b00000000
				},

				{
						0b00000001,
						0b00000001,
						0b00000001,
						0b00000001
				},

				{
						0b00000000,
						0b00001111,
						0b00000000,
						0b00000000
				}
		}
};


u16 t_pos[24];//={0};	//stores the game board: each item of this array is a line on the screen. A 1-bit is a box, 0 means empty.
						//Line 0 is full of 1 to prevent the pieces to go too much down! See function "check_collision"
						//t_pos[1] to t_pos[18] are the 18 lines
						//t_pos[20] to t_pos[23] stores the next piece.

const unsigned char number[][5] = {		//5*8
	{0x3E, 0x51, 0x49, 0x45, 0x3E},// 0
	{0x00, 0x42, 0x7F, 0x40, 0x00},// 1
	{0x42, 0x61, 0x51, 0x49, 0x46},// 2
	{0x21, 0x41, 0x45, 0x4B, 0x31},// 3
	{0x18, 0x14, 0x12, 0x7F, 0x10},// 4
	{0x27, 0x45, 0x45, 0x45, 0x39},// 5
	{0x3C, 0x4A, 0x49, 0x49, 0x30},// 6
	{0x01, 0x71, 0x09, 0x05, 0x03},// 7
	{0x36, 0x49, 0x49, 0x49, 0x36},// 8
	{0x06, 0x49, 0x49, 0x29, 0x1E},// 9
};


u8 g_falling_speed;
u16 g_score;
bit g_game_is_over;

struct _g_current_piece{	
	u8 type;
	u8 rotation;
	u8 col;
	u8 row;
} g_cur, g_next;		//the current piece and the next one!


//Prototypes :

void main(void);
u8 poll_keyboard();

void init_var();
void prepare_to_sleep();
void game_over();

void print_number(u8 nb);	//prints a number "vertically". Could easily be improved to print any character vertically. I will do it for next version, so as to display "game over" for example.
void print_score();
void display_menu(void);

u8 check_collision();	//to be called BEFORE calling draw_current !! but after having changed a value in g_cur.
void check_line();		//checks for lines, clears it and updates the score

void spawn_piece();

void draw_piece(u8 piece, u8 rotation, u8 col, u8 row);		//row € [0 (down), 17 (up)]. col € [0 (left), 11 (right)]. Don't actually draw the piece on the screen: only updates t_pos
void draw_current();
void clear_piece(u8 piece, u8 rotation, u8 col, u8 row);
void clear_current();
void draw_line(u8 line);		//redraw the whole line according to the content of t_pos[]. line is between 0 (down) and 17 (up)
void draw_board(void);

void piece_down();
void piece_left();
void piece_right();
void piece_rotate();

void timer1_isr() __interrupt (T1_VECTOR);
#define setup_game_timer() setup_T1()
void setup_T1(void);


#endif
